package coreJava.misc;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 
 * @author shivendra
 * This to simulate different class loading issues. Here TestClass is available in classpath of AppLoader and CustomClass loader. 
 * AppLoader loads it whle resolving ref on Main class loading
 *
 */

public class ClassLoading {
	
	public static void main(String[] args) throws ClassNotFoundException, Exception, IllegalAccessException {
		ClassLoader loader1 = new ClassLoader1();
		ClassLoader loader2 = new ClassLoader1();
		Class c1 = Class.forName("coreJava.misc.TestClass", false, loader1);
		Object obj = c1.newInstance();
		//TestClass is loaded by APPLoader on loading Main class when it tries to resolve the ref
		System.out.println(TestClass.class.getClassLoader().toString() +" :: "+obj.getClass().getClassLoader().toString());
		TestClass tc = (TestClass)obj;
	}
	
}

class ClassLoader1 extends ClassLoader{
	
	@Override
	public Class<?> loadClass(String aName) throws ClassNotFoundException {
		if(aName.startsWith("java.lang")) return super.loadClass(aName);
		else return findClass(aName);
	}
	
	@Override
	protected Class<?> findClass(String aName) throws ClassNotFoundException {
		String classPath = "";
		String classFilePath = classPath + aName.replace(".", File.separator) + ".class";
		byte[] classBytes = loadClassBytes(classFilePath);
		return  defineClass(null, classBytes, 0, classBytes.length);
		
	}
	
	private byte[] loadClassBytes(String classFile){
		Path path = Paths.get(classFile);
		try {
			return Files.readAllBytes(path);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}

